<?php
namespace app\protocol\commands;

class ConvTreeCommand extends BaseCommand
{
    public function execute($params, $connection): string
    {
//        $jsonData = trim($params);
        $jsonData = '[{"id":200002538,"name":"空心菜类","level":3,"namePath":"蔬菜/豆制品,叶菜类,空心菜类"},{"id":200002537,"name":"香菜类","level":3,"namePath":"蔬菜/豆制品,葱姜蒜椒/调味菜,香菜类"},{"id":200002536,"name":"紫苏/苏子叶","level":3,"namePath":"蔬菜/豆制品,叶菜类,紫苏/苏子叶"},{"id":200002543,"name":"乌塌菜/塌菜/乌菜","level":3,"namePath":"蔬菜/豆制品,叶菜类,乌塌菜/塌菜/乌菜"},{"id":200002542,"name":"菜心/菜苔类","level":3,"namePath":"蔬菜/豆制品,叶菜类,菜心/菜苔类"},{"id":200002540,"name":"马兰头/马兰/红梗菜","level":3,"namePath":"蔬菜/豆制品,叶菜类,马兰头/马兰/红梗菜"},{"id":200002531,"name":"苋菜类","level":3,"namePath":"蔬菜/豆制品,叶菜类,苋菜类"},{"id":200002528,"name":"其他叶菜类","level":3,"namePath":"蔬菜/豆制品,叶菜类,其他叶菜类"}]'; // 这里可以放入您完整的JSON数据

//        print_r($jsonData);die;
        if (empty($jsonData)) {
            throw new \InvalidArgumentException("请提供JSON数据，使用: " . self::getUsage());
        }

        $data = json_decode($jsonData, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new \InvalidArgumentException("JSON格式错误: " . json_last_error_msg());
        }

        if (!is_array($data)) {
            throw new \InvalidArgumentException("JSON数据必须是数组");
        }
        $tree = $this->buildTree($data);
        return $this->formatTreeOutput($tree);
    }

    /**
     * 构建三级树形结构
     */
    protected function buildTree(array $items): array
    {
        $tree = [];
        $nodeMap = []; // 用于快速查找节点的映射表

        // 第一遍：创建所有节点并建立映射[3](@ref)
        foreach ($items as $item) {
            if (!isset($item['namePath'])) {
                continue;
            }

            $pathParts = explode(',', $item['namePath']);
            $pathParts = array_map('trim', $pathParts);


            // 确保至少有三级路径
            if (count($pathParts) < 3) {
                continue;
            }

            // 处理每一级节点[6](@ref)
            for ($i = 0; $i < min(3, count($pathParts)); $i++) {
                $currentPath = implode(',', array_slice($pathParts, 0, $i + 1));
                $pathKey = md5($currentPath);

                if (!isset($nodeMap[$pathKey])) {
                    $nodeMap[$pathKey] = [
                        'id' => $this->generateRandomId(),
                        'name' => $pathParts[$i],
                        'level' => $i + 1,
                        'name_path' => $currentPath,
                        'parent_id' => $i > 0 ? $this->getParentId($pathParts, $i, $nodeMap) : 0,
                        'is_leaf' => $i === 2 ? 1 : 2, // 第三级是叶子节点
                        'children' => []
                    ];

                    // 构建id_path
                    if ($i === 0) {
                        $nodeMap[$pathKey]['id_path'] = ',' . $nodeMap[$pathKey]['id'] . ',';
                    } else {
                        $parentPath = implode(',', array_slice($pathParts, 0, $i));
                        $parentKey = md5($parentPath);
                        $nodeMap[$pathKey]['id_path'] = $nodeMap[$parentKey]['id_path'] . $nodeMap[$pathKey]['id'] . ',';
                    }

                    // 第三级节点使用原始ID
                    if ($i === 2 && isset($item['id'])) {
                        $nodeMap[$pathKey]['id'] = (string)$item['id'];
                        $nodeMap[$pathKey]['id_path'] = substr($nodeMap[$pathKey]['id_path'], 0, -1) . $item['id'] . ',';
                    }
                }
            }
        }

        // 第二遍：构建层级关系（使用引用并正确管理）
        foreach ($nodeMap as $key => &$node) {
            if ($node['level'] === 1) {
                $tree[] = &$node;
            } else {
                $pathParts = explode(',', $node['name_path']);
                $parentPath = implode(',', array_slice($pathParts, 0, count($pathParts) - 1));
                $parentKey = md5($parentPath);

                if (isset($nodeMap[$parentKey])) {
                    $nodeMap[$parentKey]['children'][] = &$node;
                }
            }
        }
        unset($node);
        return $tree;
    }

    /**
     * 生成随机10位ID
     */
    protected function generateRandomId($length = 10): string
    {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $randomString = '';
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[rand(0, strlen($characters) - 1)];
        }
        return $randomString;
    }

    /**
     * 获取父节点ID
     */
    protected function getParentId(array $pathParts, int $currentLevel, array $nodeMap): string
    {
        if ($currentLevel === 0) {
            return '0';
        }

        $parentPath = implode(',', array_slice($pathParts, 0, $currentLevel));
        $parentKey = md5($parentPath);

        return isset($nodeMap[$parentKey]) ? $nodeMap[$parentKey]['id'] : '0';
    }

    /**
     * 格式化树形结构输出
     */
    protected function formatTreeOutput(array $tree): string
    {
        return json_encode($tree, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    }

    /**
     * 构建树形结构的替代方法（使用递归）[6](@ref)
     */
    protected function buildTreeRecursive(array $items, $parentPath = '', $level = 1): array
    {

        $tree = [];

        foreach ($items as $item) {
            if (!isset($item['namePath'])) {
                continue;
            }

            $pathParts = explode(',', $item['namePath']);
            $pathParts = array_map('trim', $pathParts);
            $currentPath = implode(',', array_slice($pathParts, 0, $level));


            // 如果当前路径匹配父路径，或者是根节点
            if (($level === 1 && $parentPath === '') ||
                ($level > 1 && $currentPath === $parentPath)) {

                $node = [
                    'id' => $level === 3 ? (string)$item['id'] : $this->generateRandomId(),
                    'name' => $pathParts[$level - 1],
                    'level' => $level,
                    'name_path' => $currentPath,
                    'parent_id' => $level === 1 ? '0' : $this->getParentIdFromPath($currentPath),
                    'is_leaf' => $level === 3 ? 1 : 2
                ];

                // 递归构建子节点
                $node['children'] = $this->buildTreeRecursive($items, $currentPath, $level + 1);


                $tree[] = $node;
            }
        }

        return $tree;
    }

    /**
     * 从路径获取父节点ID（简化版）
     */
    protected function getParentIdFromPath(string $currentPath): string
    {
        $parts = explode(',', $currentPath);
        array_pop($parts); // 移除最后一部分得到父路径
        $parentPath = implode(',', $parts);

        // 这里应该根据路径查找父节点ID，简化处理
        return md5($parentPath);
    }

    /**
     * 优化的树构建方法（使用哈希表）[3](@ref)
     */
    protected function buildTreeOptimized(array $items): array
    {
        $pathMap = [];
        $tree = [];

        // 第一遍：按路径分组
        foreach ($items as $item) {
            if (!isset($item['namePath'])) {
                continue;
            }

            $pathParts = explode(',', $item['namePath']);
            $pathParts = array_map('trim', $pathParts);

            for ($i = 0; $i < min(3, count($pathParts)); $i++) {
                $pathKey = implode(',', array_slice($pathParts, 0, $i + 1));

                if (!isset($pathMap[$pathKey])) {
                    $pathMap[$pathKey] = [
                        'name' => $pathParts[$i],
                        'level' => $i + 1,
                        'children' => [],
                        'items' => []
                    ];
                }

                if ($i === 2) { // 第三级节点
                    $pathMap[$pathKey]['items'][] = $item;
                }
            }
        }

        // 第二遍：构建树形结构
        foreach ($pathMap as $path => $nodeData) {
            $pathParts = explode(',', $path);
            $level = $nodeData['level'];

            if ($level === 1) {
                $treeNode = $this->createTreeNode($pathParts[0], $level, $path);
                $treeNode['children'] = $this->buildChildrenForPath($path, $pathMap, 2);
                $tree[] = $treeNode;
            }
        }

        return $tree;
    }

    /**
     * 为指定路径构建子节点
     */
    protected function buildChildrenForPath(string $parentPath, array $pathMap, int $targetLevel): array
    {
        $children = [];

        foreach ($pathMap as $path => $nodeData) {
            if ($nodeData['level'] !== $targetLevel) {
                continue;
            }

            // 检查是否是父路径的直接子节点
            $pathParts = explode(',', $path);
            $parentPathCheck = implode(',', array_slice($pathParts, 0, $targetLevel - 1));

            if ($parentPathCheck === $parentPath) {
                $childNode = $this->createTreeNode($pathParts[$targetLevel - 1], $targetLevel, $path);

                if ($targetLevel < 3) {
                    $childNode['children'] = $this->buildChildrenForPath($path, $pathMap, $targetLevel + 1);
                } else {
                    // 第三级节点，添加具体项目
                    foreach ($nodeData['items'] as $item) {
                        $leafNode = [
                            'id' => (string)$item['id'],
                            'name' => $item['name'],
                            'level' => 3,
                            'name_path' => $item['namePath'],
                            'parent_id' => $this->generateRandomId(), // 这里应该是父节点的ID
                            'is_leaf' => 1
                        ];
                        $childNode['children'][] = $leafNode;
                    }
                }

                $children[] = $childNode;
            }
        }

        return $children;
    }

    /**
     * 创建树节点
     */
    protected function createTreeNode(string $name, int $level, string $path): array
    {
        return [
            'id' => $level === 3 ? '' : $this->generateRandomId(),
            'name' => $name,
            'level' => $level,
            'name_path' => $path,
            'parent_id' => $level === 1 ? '0' : $this->generateRandomId(),
            'is_leaf' => $level === 3 ? 1 : 2,
            'children' => []
        ];
    }

    public static function getDescription(): string
    {
        return 'JSON转树结构: conv_tree <json_data>';
    }

    public static function getUsage(): string
    {
        return "conv_tree [{\"namePath\":\"一级,二级,三级\",\"name\":\"节点名\",\"id\":123}]";
    }
}